package com.stars.easyms.proxy;

import com.alibaba.fastjson.JSON;
import com.stars.easyms.base.alarm.EasyMsAlarmAssistor;
import com.stars.easyms.base.bean.EasyMsResponseEntity;
import com.stars.easyms.base.bean.LazyLoadBean;
import com.stars.easyms.base.util.EasyMsResponseEntityUtil;
import com.stars.easyms.base.util.ReflectUtil;
import com.stars.easyms.proxy.exception.EasyMsProxyRuntimeException;
import com.stars.easyms.proxy.service.EasyMsRestProxyService;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>className: AbstractEasyMsProxyMethodInterceptor</p>
 * <p>description: EasyMs代理方法拦截器抽象类</p>
 *
 * @author guoguifang
 * @version 1.7.3
 * @date 2021/3/26 3:46 下午
 */
class BaseEasyMsProxyMethodInterceptor {

    private static final LazyLoadBean<EasyMsRestProxyService> easyMsRestProxyService =
            new LazyLoadBean<>(EasyMsRestProxyService.class, BaseEasyMsRestProxyService::new);

    protected Object intercept(Object obj, Method method, Object[] args) {
        EasyMsProxyInfo easyMsProxyInfo = EasyMsProxyServiceRegistrar.getEasyMsProxyInfo(method);
        if (easyMsProxyInfo == null) {
            throw new EasyMsProxyRuntimeException("Can't find the method '{}' proxy info!", ReflectUtil.getMethodFullName(method));
        }

        String arg = "{}";
        Parameter[] methodParameters = easyMsProxyInfo.getMethodParameters();
        if (methodParameters.length > 1) {
            Map<String, Object> parameterMap = new HashMap<>(8);
            for (int i = 0; i < methodParameters.length; i++) {
                parameterMap.put(methodParameters[i].getName(), args[i]);
            }
            arg = JSON.toJSONString(parameterMap);
        } else if (methodParameters.length == 1 && args[0] != null) {
            arg = JSON.toJSONString(args[0]);
        }

        String targetCode = easyMsProxyInfo.getTarget();
        String url = easyMsProxyInfo.getUrl();
        String path = easyMsProxyInfo.getPath();
        String result = easyMsRestProxyService.getNonNullBean().restProxy(targetCode, url, path, arg);
        Type returnType = easyMsProxyInfo.getReturnType();

        Object object;
        try {
            if (EasyMsResponseEntityUtil.isEasyMsResponseEntityType(returnType)) {
                object = JSON.parseObject(result, returnType);
            } else {
                object = JSON.parseObject(result, EasyMsResponseEntityUtil.getEasyMsResponseEntityParameterizedType(returnType));
            }
        } catch (Exception e) {

            // 记录错误信息并告警
            EasyMsAlarmAssistor.sendExceptionAlarmMessage(e);

            throw new EasyMsProxyRuntimeException("解析响应数据'{}'失败!", result);
        }

        // 如果返回的Type不是EasyMsResponseEntity类型的，则判断是否成功，如果返回的信息不是正确信息，则抛出异常
        if (!EasyMsResponseEntityUtil.isEasyMsResponseEntityType(returnType) && object instanceof EasyMsResponseEntity) {
            EasyMsResponseEntity<?> responseEntity = (EasyMsResponseEntity) object;
            if (!responseEntity.isSuccess()) {
                throw new EasyMsProxyRuntimeException(responseEntity.toString());
            }
            if (responseEntity.getBody() != null) {
                return responseEntity.getBody();
            }
            return returnType == Boolean.class || returnType == boolean.class ? Boolean.TRUE : null;
        }
        return object;
    }

}
